package com.example.demo.mvc;

import com.example.demo.dto.ResultDTO;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;


@ControllerAdvice
public class GlobalAdviceHandler implements ResponseBodyAdvice<Object>, ApplicationContextAware {

    private ApplicationContext applicationContext;

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResultDTO handleException(HttpServletResponse response, Exception ex) {
        System.out.println("程序异常：" + ex.toString());
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        return new ResultDTO("100101", ex.getMessage());
    }

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
        Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        // Annotation[] as = returnType.getMethodAnnotations();
        boolean flag1 = returnType.hasParameterAnnotation(WithApiResult.class);
        boolean flag2 = returnType.hasMethodAnnotation(WithApiResult.class);
        AnnotatedElement annotatedElement = returnType.getAnnotatedElement();
        Annotation as = annotatedElement.getDeclaredAnnotation(WithApiResult.class);

        System.out.println(returnType.getContainingClass().getAnnotation(WithApiResult.class));

        Annotation[] aa = returnType.getExecutable().getDeclaredAnnotations();
        System.out.println(returnType.getClass().toString());
        Annotation b = returnType.getClass().getAnnotation(WithApiResult.class);

        if (body instanceof ResultDTO) {
            return body;
        }

        // 类注解
        Annotation withApiResultAnnotation = returnType.getContainingClass().getAnnotation(WithApiResult.class);
        if (withApiResultAnnotation != null) {
            return ResultDTO.success(body);
        }

        // 方法注解
        if (returnType.hasMethodAnnotation(WithApiResult.class)) {
            return ResultDTO.success(body);
        }
        return body;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
